package com.youdianda.service.impl;

import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;

import com.youdianda.dto.ArticlePageQueryByCateIdDTO;
import com.youdianda.dto.ArticlePageQueryDTO;
import com.youdianda.dto.UserDTO;
import com.youdianda.entity.*;

import com.youdianda.mapper.SysConfigMapper;
import com.youdianda.mapper.YddArticleMapper;
import com.youdianda.result.PageResult;
import com.youdianda.result.Result;
import com.youdianda.service.*;
import com.youdianda.utils.JwtUtil;
import com.youdianda.vo.*;
import org.apache.velocity.runtime.directive.contrib.For;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.DigestUtils;

import java.util.ArrayList;
import java.util.List;


@Service
public class NewArticlesServiceImpl implements NewArticlesService {

    @Autowired
    private IYddArticleService iYddArticleService;
    @Autowired
    private IYddCateService iYddCateService;
    @Autowired
    private ISysConfigService iSysConfigService;
    @Autowired
    private SysConfigMapper sysConfigMapper;
    @Autowired
    private IYddTagService iYddTagService;
    @Autowired
    private IYddAdvimgService iYddAdvimgService;
    @Autowired
    private IYddUserService iYddUserService;
    @Autowired
    private IYddUserDataService iYddUserDataService;






    /**
     * 网页前端：最近更新
     *
     * @param dto
     * @return
     */
    @Override
    public Result getArticlePage(ArticlePageQueryDTO dto) {
        if(dto == null){
            Result.error("最近更新文章失败...");
        }
        dto.setPage(1);
        dto.setLimit(5);

        LambdaQueryWrapper <YddArticle>  lqw = new  LambdaQueryWrapper <YddArticle>( );

        //1、获取vo
        NewArticlesVO newArticlesVO = new NewArticlesVO();
        //1.1 封装数据描述
        newArticlesVO.setDesc("最近更新");


        Long now = System.currentTimeMillis();
        Long oneDay = now - 1000*60*60*24;
        Long oneWeek = now - 1000*60*60*24*7;


        //1.2 得到时间，24小时以内的文章数量
        lqw.le(YddArticle::getCreateDate, now).ge(YddArticle::getCreateDate, oneDay);
        Long num_day = iYddArticleService.count(lqw);
        newArticlesVO.setNum_day(num_day.intValue());
        lqw.clear();

        //1.3   一周内最新文章的数量
        lqw.le(YddArticle::getCreateDate, now).ge(YddArticle::getCreateDate,oneWeek);
        Long num_week = iYddArticleService.count(lqw);
        newArticlesVO.setNum_week(num_week.intValue());
        lqw.clear();

        //1.4   分页得到这一周的所有文章
        lqw.le(YddArticle::getCreateDate, now).ge(YddArticle::getCreateDate,oneWeek);
        Page<YddArticle> page = new Page<>();
        page.setSize(dto.getLimit());
        page.setCurrent(dto.getPage());

        Page<YddArticle> yddArticlePage = iYddArticleService.page(page, lqw);


        //2 封装PageResult
        PageResult pageResult = new PageResult();
        pageResult.setData(yddArticlePage.getRecords());//封装分页结果

        pageResult.setPageSize(dto.getPage());//当前页码

        pageResult.setCurrentPage(dto.getLimit()); //每页数量

        pageResult.setCount((int) yddArticlePage.getTotal());//总记录数

        long totalPages = 1 + pageResult.getCount() / pageResult.getPageSize();
        pageResult.setTotalPages((int) totalPages);


        newArticlesVO.setList(pageResult);
        return Result.success(newArticlesVO);
    }




    /**
     * 根据分类ID分页文章
     *
     * @return
     */
    @Override
    public Result getArticlePageByCateid(ArticlePageQueryByCateIdDTO dto) {
        if(dto == null){
            return Result.error("获得分类信息失败...");
        }

        LambdaQueryWrapper <YddArticle>  lqw = new  LambdaQueryWrapper <YddArticle>( );

        Page<YddArticle> page = new Page<>();
        page.setSize(dto.getLimit());
        page.setCurrent(dto.getPage());
        lqw.eq(YddArticle::getCateid,dto.getCateid());
        Page<YddArticle> yddArticlePage = iYddArticleService.page(page, lqw);

        for (YddArticle yddArticle : yddArticlePage.getRecords()) {
            Integer cateid = yddArticle.getCateid();
            String catename = iYddCateService.getById(cateid).getCatename();
            yddArticle.setCateName(catename);
        }

        //2 封装PageResult
        PageResult pageResult = new PageResult();
        pageResult.setData(yddArticlePage.getRecords());//封装分页结果

        pageResult.setPageSize(dto.getPage());//当前页码

        pageResult.setCurrentPage(dto.getLimit()); //每页数量

        pageResult.setCount((int) yddArticlePage.getTotal());//总记录数

        long totalPages = 1 + pageResult.getCount() / pageResult.getPageSize();
        pageResult.setTotalPages((int) totalPages);

        NewArticlesVO newArticlesVO = new NewArticlesVO();
        newArticlesVO.setList(pageResult);
        return Result.success(newArticlesVO);
    }














    /**
     * 主页所有基础模块
     *
     * @return
     */
    @Override
    public Result indexAll() {

        IndexVO indexVO = new IndexVO();

        //1 查询获得allCate
        List<YddCate> cateList = iYddCateService.list();
        indexVO.setAllCate(cateList);


        //3 封装allTag
        List<YddTag> yddTagList = iYddTagService.list();
        indexVO.setAllTag(yddTagList);

        //4 封装banner
        LambdaQueryWrapper <YddAdvimg>  lqwYddAdvimg = new  LambdaQueryWrapper <YddAdvimg>( );
        lqwYddAdvimg.eq(YddAdvimg::getAdvimgpos, "15");
        List<YddAdvimg> banner = iYddAdvimgService.list(lqwYddAdvimg);
        indexVO.setBanner(banner);
        lqwYddAdvimg.clear();

        //5 封装showBanner
        List<YddAdvimg> showBanner = iYddAdvimgService.list();
        indexVO.setShowBanner(showBanner);








        //2 封装Config类
        Config config = new Config();
        List<SysConfig> sysConfigList = iSysConfigService.list();
        LambdaQueryWrapper <SysConfig>  lqwSysConfig = new  LambdaQueryWrapper <SysConfig>( );


        //2.1 封装allData
        List<ConfigAlldata> list = new ArrayList<>();
        for (SysConfig sysConfig : sysConfigList) {
            ConfigAlldata configAlldata = new ConfigAlldata();
            BeanUtils.copyProperties(sysConfig, configAlldata);
            list.add(configAlldata);
        }
        config.setAllData(list);

        //2.2 封装list
        List<String> tabValue = sysConfigMapper.getTabValue();
        List<ConfigList> allData = new ArrayList<>();

        for (String s1 : tabValue) {
            ConfigList configList = new ConfigList();
            configList.setKey(s1);
            allData.add(configList);

            List<String> groupValue = sysConfigMapper.getGroupValues(s1);
            List<ConfigListChildren> children = new ArrayList<>();
            for (String s2 : groupValue) {
                ConfigListChildren configListChildren = new ConfigListChildren();
                configListChildren.setName(s2);
                children.add(configListChildren);
                lqwSysConfig.eq(SysConfig::getGroupValue, s2);
                List<SysConfig> sysConfigs = iSysConfigService.list(lqwSysConfig);
                configListChildren.setData(sysConfigs);
                lqwSysConfig.clear();
            }
            configList.setChildren(children);
        }
        config.setList(allData);

        indexVO.setConfig(config);

        return Result.success(indexVO);
    }

    /**
     * 最新文章
     *
     * @return
     */
    @Override
    public Result getNewArticle() {
        LambdaQueryWrapper <YddArticle>  lqw = new  LambdaQueryWrapper <YddArticle>( );

        lqw.orderByAsc(YddArticle::getClick);
        List<YddArticle> list = iYddArticleService.list(lqw);

        List<YddArticle> yddArticleList = new ArrayList<>();
        for (int i = 0; i < 8; i++) {
            yddArticleList.add(list.get(i));
        }

        for (YddArticle yddArticle : yddArticleList) {
            Integer cateid = yddArticle.getCateid();
            String catename = iYddCateService.getById(cateid).getCatename();
            yddArticle.setCateName(catename);
        }

        HotArticlesVO hotArticlesVO = new HotArticlesVO("侧边最新文章" , yddArticleList);
        return Result.success(hotArticlesVO);
    }

    /**
     * 推荐文章
     *
     * @return
     */
    @Override
    public Result getrecommendArticle() {
        LambdaQueryWrapper <YddArticle>  lqw = new  LambdaQueryWrapper <YddArticle>( );


        lqw.orderByDesc(YddArticle::getLovenum);
        List<YddArticle> list = iYddArticleService.list(lqw);

        List<YddArticle> yddArticleList = new ArrayList<>();
        for (int i = 0; i < 8; i++) {
            yddArticleList.add(list.get(i));
        }

        for (YddArticle yddArticle : yddArticleList) {
            Integer cateid = yddArticle.getCateid();
            String catename = iYddCateService.getById(cateid).getCatename();
            yddArticle.setCateName(catename);
        }

        HotArticlesVO hotArticlesVO = new HotArticlesVO("侧边推荐文章" , yddArticleList);
        return Result.success(hotArticlesVO);
    }

    /**
     * 注册
     *
     * @param dto
     * @return
     */
    @Override
    @Transactional
    public Result reg(UserDTO dto) {
        if(dto == null){
            return Result.error("获取注册信息失败...");
        }
        LambdaQueryWrapper<YddUser> lqw = new LambdaQueryWrapper();

        lqw.eq(YddUser::getMobile, dto.getMobile());
        YddUser checkUser = iYddUserService.getOne(lqw);

        if(checkUser != null){
            return Result.error("该注册账号已经存在，注册失败...");
        }

        String pwd = DigestUtils.md5DigestAsHex(dto.getPassword().getBytes());
        YddUser newUser = YddUser.builder()
                .username(dto.getMobile())
                .mobile(dto.getMobile())
                .password(pwd)
                .build();
        iYddUserService.save(newUser);

        Token token = Token.builder().token(JwtUtil.getToken(newUser.getId().longValue())).build();


        return Result.success(token);
    }

    /**
     * 文章详情数据
     *
     * @param id
     * @return
     */
    @Override
    public Result showArticles(Integer id) {
        if(id == null){
            return Result.error("相关文章不存在...");
        }
        LambdaQueryWrapper<YddArticle> lqwYddArticle = new LambdaQueryWrapper();
        LambdaQueryWrapper<YddUserData> lqwYddUserData = new LambdaQueryWrapper();

        ShowYddArticleVO showYddArticleVO = new ShowYddArticleVO();


        //1 封装info
        lqwYddArticle.eq(YddArticle::getId , id);
        YddArticle thisOne = iYddArticleService.getOne(lqwYddArticle);
        showYddArticleVO.setInfo(thisOne);
        lqwYddArticle.clear();

        //2 封装recommend
        Integer userId = thisOne.getUserId();
        lqwYddUserData.eq(YddUserData::getUserId, userId)
                .orderByDesc(YddUserData::getArticleId);
        List<YddUserData> userDataList = iYddUserDataService.list(lqwYddUserData);
        lqwYddUserData.clear();

        List<YddArticle> yddArticleList = new ArrayList<>();
        for (YddUserData yddUserData : userDataList) {
            lqwYddArticle.eq(YddArticle::getId, yddUserData.getArticleId());
            YddArticle yddArticle = iYddArticleService.getOne(lqwYddArticle);
            yddArticleList.add(yddArticle);
        }
        showYddArticleVO.setRecommend(yddArticleList);
        lqwYddArticle.clear();


        //3 封装prev、next
        lqwYddUserData.select(YddUserData::getArticleId);
        lqwYddUserData.eq(YddUserData::getUserId, userId)
                .orderByDesc(YddUserData::getArticleId);

        List<YddUserData> yddUserDataList = iYddUserDataService.list(lqwYddUserData);
        /*
            获得该作者的全部文章ID，并且按降序排序
         */
        List<Integer> articleIdList = new ArrayList();

        for (YddUserData yddUserData : yddUserDataList) {
            articleIdList.add(yddUserData.getArticleId());
        }

        //获得当前文章的排序序列号。
        int n = articleIdList.indexOf(id);

        if(n < 0){
            ArticleLink next = new ArticleLink();
            next.setId(181);
            lqwYddArticle.eq(YddArticle::getId,181);
            String title = iYddArticleService.getOne(lqwYddArticle).getTitle();
            next.setTitle(title);
            List nextList = new ArrayList();
            nextList.add(next);
            showYddArticleVO.setNext(nextList);

            lqwYddArticle.clear();

            ArticleLink prev = new ArticleLink();
            prev.setId(171);
            lqwYddArticle.eq(YddArticle::getId,171);
            title = iYddArticleService.getOne(lqwYddArticle).getTitle();
            prev.setTitle(title);
            List prevList = new ArrayList();
            prevList.add(prev);
            showYddArticleVO.setPrev(prevList);

            return Result.success(showYddArticleVO);
        }

        if(n == 0 && articleIdList.size() == 1){
            showYddArticleVO.setNext(null);
            showYddArticleVO.setPrev(null);

        }else if(n == 0){
            ArticleLink next = new ArticleLink();
            next.setId(articleIdList.get(1));
            lqwYddArticle.eq(YddArticle::getId,next.getId());
            String title = iYddArticleService.getOne(lqwYddArticle).getTitle();
            next.setTitle(title);
            List nextList = new ArrayList();
            nextList.add(next);
            showYddArticleVO.setNext(nextList);

        }else if(n+1 == articleIdList.size()){
            ArticleLink prev = new ArticleLink();
            prev.setId(articleIdList.get(n-1));
            lqwYddArticle.eq(YddArticle::getId,prev.getId());
            String title = iYddArticleService.getOne(lqwYddArticle).getTitle();
            prev.setTitle(title);
            List prevList = new ArrayList();
            prevList.add(prev);
            showYddArticleVO.setPrev(prevList);

        }else {
            ArticleLink next = new ArticleLink();
            next.setId(articleIdList.get(1));
            lqwYddArticle.eq(YddArticle::getId,next.getId());
            String title = iYddArticleService.getOne(lqwYddArticle).getTitle();
            next.setTitle(title);
            List nextList = new ArrayList();
            nextList.add(next);
            showYddArticleVO.setNext(nextList);

            lqwYddArticle.clear();

            ArticleLink prev = new ArticleLink();
            prev.setId(articleIdList.get(n-1));
            lqwYddArticle.eq(YddArticle::getId,prev.getId());
            title = iYddArticleService.getOne(lqwYddArticle).getTitle();
            prev.setTitle(title);
            List prevList = new ArrayList();
            prevList.add(prev);
            showYddArticleVO.setPrev(prevList);
        }


        System.out.println("===================");
        return Result.success(showYddArticleVO);
    }


}
